﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using System.Net.Mail;
using System.IO;
using NHibernate.Criterion;

namespace Mailer.Model.Types
{
	public class List
	{
		public virtual Guid ID { get; set; }
		public virtual Guid ApplicationID { get; set; }

		public virtual string ShortName { get; set; }
		public virtual string Name { get; set; }

		public virtual DateTime CreatedDate { get; set; }
		public virtual DateTime UpdatedDate { get; set; }

		public virtual Guid CreatedBy { get; set; }
		public virtual Guid UpdatedBy { get; set; }

		public virtual int State { get; set; }
		public virtual IList<ListProperty> Properties { get; set; }

		public virtual IList<Recipient> Recipients { get; set; }
		public virtual IList<Mail> Mails { get; set; }

		public virtual bool IsPublic { get; set; }

		public List()
		{
			Properties = new List<ListProperty>();
			Recipients = new List<Recipient>();
			Mails = new List<Mail>();
		}

		public virtual int NumRecipients
		{
			get
			{
				return Recipients.Count;
			}
		}


		public virtual bool AddRecipient(ISession sess, ITransaction transaction, MailAddress address, bool addexisting, bool manualinput)
		{
			return AddRecipient(sess, transaction, address.Address, address.DisplayName, addexisting,manualinput);
		}

		public virtual bool AddRecipient(ISession sess, ITransaction transaction, string emailaddress, bool addexisting, bool manualinput)
		{
			return AddRecipient(sess, transaction, emailaddress, "", addexisting, manualinput);
		}

		public virtual bool AddRecipient(ISession sess, ITransaction transaction, string emailaddress, string displayname, bool addexisting, bool manualinput)
		{
			bool ret = false;

			Recipient recip = sess.CreateCriteria<Recipient>().Add(Expression.Eq("Email", emailaddress)).Add(Expression.Eq("ApplicationID", this.ApplicationID)).UniqueResult<Recipient>();
			if (recip != null)
			{
				// mottagaren finns i registret, ska han läggas till i listan här? han kanske har valt att avregga sig

				recip.UpdatedBy = Guid.Empty;
				recip.UpdatedDate = DateTime.Now;

				if (manualinput)
				{	
					if (recip.State == (int)RecipientState.NotWorking) // retry
						recip.State = (int)RecipientState.New;
				}

				if (addexisting)
				{
					if (!recip.Lists.Contains(this))
					{
						recip.Lists.Add(this);
						ret = true;
					}
				}

				sess.Save(recip);
				if (!string.IsNullOrEmpty(displayname))
					recip.SetPropertyValue(sess, "displayname", displayname);
			}
			else
			{
				// mottagaren är inte tidigare registrerad, lägg till i listan.

				Recipient newrecip = new Recipient();

				newrecip.ApplicationID = this.ApplicationID;

				newrecip.Lists.Add(this);

				newrecip.Email = emailaddress;
				newrecip.CreatedBy = Guid.Empty;
				newrecip.CreatedDate = DateTime.Now;
				newrecip.UpdatedBy = Guid.Empty;
				newrecip.UpdatedDate = DateTime.Now;

				if (manualinput)
					newrecip.State = (int)RecipientState.Verified;
				else
					newrecip.State = (int)RecipientState.New;
				sess.Save(newrecip);

				if (!string.IsNullOrEmpty(displayname))
					newrecip.SetPropertyValue(sess, "displayname", displayname);

				ret = true;
			}

			return ret;
		}

		public virtual bool RemoveRecipient(ISession sess, ITransaction transaction, MailAddress address)
		{
			return RemoveRecipient(sess, transaction, address.Address);
		}

		public virtual bool RemoveRecipient(ISession sess, ITransaction transaction, string emailaddress)
		{
			return false;
		}

		public virtual bool AddRecipientsFromFile(ISession sess, ITransaction transaction, Stream filestream, string fileformat, bool addexisting, out int numfound, out int numadded)
		{
			StreamReader sr = new StreamReader(filestream);
			string alldata = sr.ReadToEnd();

			//	Response.Write("<p>" + alldata + "</p>");
			int found = 0;
			int ok = 0;
			int added = 0;

			string[] items = null;

			switch (fileformat)
			{
				default:
				case "enter":
					items = alldata.Split(new char[] { '\n', '\r' });
					break;

				case "csv":
					items = alldata.Split(new char[] { ',' });
					break;

				case "tsv":
					items = alldata.Split(new char[] { '\t' });
					break;
			}

			if (items != null)
			{
				foreach (string s in items)
				{
					string s2 = s.Trim();
					if (s2 != "")
					{
						found++;
						try
						{
							MailAddress addr = new MailAddress(s2);
							if (addr != null)
							{
								ok++;
								if (AddRecipient(sess, transaction, addr, addexisting, false))
									added++;
							}
						}
						catch (Exception)
						{
						}
					}
				}
			}

			// Response.Write("added=" + added + ", ok=" + ok + ", found=" + found);

			numadded = added;
			//	numdupes = ok - added;
			numfound = ok;

			return (ok > 0);
		}

	}
}
